#ifndef __cpu_h__
#define __cpu_h__

#include "arm.h"
#include "regfile.h"
#include "mmu.h"
#include "cp15.h"

class CCPU
{
	CMMU mmu;
	CRegisterFile regfile;



	//
	// fault and reason
	//
	bool fault;
	__u32 va;
	__u32 errcode;

	__u32 intr;
	bool int_ban;

	//ARM_STATE state;
	union
	{
		ARM_INSN_INFO arm_insn;
		THUMB_INSN_INFO thumb_insn;
	};
public:
	CCPU():int_ban(false) {}

	void reset();
	bool do_clock();
	int do_irq();
	int do_fiq();
	void assert_intr(__u32 line_mask);
	void set_cpsr(__u32 v);
	bool InAPrivilegedMode(){return regfile.mode!=MODE_USER;}

	bool CurrentModeHasSPSR(){
		return regfile.mode!=MODE_USER
			&&regfile.mode!=MODE_SYSTEM;
	}


	__u32 read_register(int reg_no);
	void exec_arm_fmt10(PARM_STATE p_state,ARM_INSN_INFO insn_info);
	__u32 arm_shifter_operand2(ARM_INSN_INFO insn_info,bool *p_shifter_carry_out);

	int exec_thumb();
	bool exec_arm();
	bool exec_arm_fmt10();
	void exec_swi();

	bool swp();
	void exec_irq();
	void exec_fiq();
	void exec_ud();
	void exec_bkpt();
	void exec_prefetch_abort();
	void exec_data_abort();
	//void exec_arm_fmt10(ARM_INSN_INFO insn_info);
	//__u32 arm_shifter_operand2(ARM_INSN_INFO insn_info,bool *p_shifter_carry_out);

	//void set_cpsr(__u32 v);

	bool read_byte (__u32 address,__u8 *p_dat );
	bool read_short(__u32 address,__u16 *p_dat );
	bool read_int(__u32 address,__u32 *p_dat );
	bool read_insn(__u32 address,__u32 *p_dat );

	bool write_byte (__u32 address,__u8  dat);
	bool write_short(__u32 address,__u16 dat);
	bool write_int(__u32 address,__u32 dat);

	// debug interface
	void dump_string(unsigned long address);
	void dump_mem(unsigned long address,unsigned long _size);
	void dump_stack();
};
#endif //__cpu_h__